﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

using BestEasy.Core;
using BestEasy.Core.UnitOfWork;

namespace BestEasy.Data
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly Dictionary<IAggregateRoot, IUnitOfWorkRepository> _addedEntities;
        private readonly Dictionary<IAggregateRoot, IUnitOfWorkRepository> _changedEntities;
        private readonly Dictionary<IAggregateRoot, IUnitOfWorkRepository> _deletedEntities;

        public UnitOfWork()
        {
            _addedEntities = new Dictionary<IAggregateRoot, IUnitOfWorkRepository>();
            _changedEntities = new Dictionary<IAggregateRoot, IUnitOfWorkRepository>();
            _deletedEntities = new Dictionary<IAggregateRoot, IUnitOfWorkRepository>();
        }
        public void RegisterAdd(IAggregateRoot entity, IUnitOfWorkRepository unitOfWorkRepository)
        {
            if (entity == null)
                throw new ArgumentNullException("entity");
            if (!_addedEntities.ContainsKey(entity))
                _addedEntities.Add(entity, unitOfWorkRepository);
        }

        public void RegisterDelete(IAggregateRoot entity, IUnitOfWorkRepository unitOfWorkRepository)
        {
            if (entity == null)
                throw new ArgumentNullException("entity");
            if (!_deletedEntities.ContainsKey(entity))
                _deletedEntities.Add(entity, unitOfWorkRepository);
        }

        public void RegisterUpdate(IAggregateRoot entity, IUnitOfWorkRepository unitOfWorkRepository)
        {
            if (entity == null)
                throw new ArgumentNullException("entity");
            if (!_changedEntities.ContainsKey(entity))
                _changedEntities.Add(entity, unitOfWorkRepository);
        }
        public void Commit()
        {
            using (var scope = new TransactionScope()) {
                foreach (IAggregateRoot entity in _addedEntities.Keys)
                {
                    _addedEntities[entity].PersistCreationOf(entity);
                }
                foreach (IAggregateRoot entity in _changedEntities.Keys)
                {
                    _changedEntities[entity].PersistUpdateOf(entity);
                }
                foreach (IAggregateRoot entity in _deletedEntities.Keys)
                {
                    _deletedEntities[entity].PersistDeletionOf(entity);
                }
                scope.Complete();//事务完成
            };
        }
    }
}
